home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / Harvest C 1.3 / Source Code / optimize.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-15  |  20.7 KB  |  891 lines  |  [TEXT/ALFA]

  1. /*
  2.     Harvest C
  3.     Copyright 1992 Eric W. Sink.  All rights reserved.
  4.     
  5.     This file is part of Harvest C.
  6.     
  7.     Harvest C is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU Generic Public License as published by
  9.     the Free Software Foundation; either version 2, or (at your option)
  10.     any later version.
  11.     
  12.     Harvest C is distributed in the hope that it will be useful,
  13.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.     GNU General Public License for more details.
  16.     
  17.     You should have received a copy of the GNU General Public License
  18.     along with Harvest C; see the file COPYING.  If not, write to
  19.     the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  20.     
  21.     Harvest C is not in any way a product of the Free Software Foundation.
  22.     Harvest C is not GNU software.
  23.     Harvest C is not public domain.
  24.  
  25.     This file may have other copyrights which are applicable as well.
  26.  
  27. */
  28.  
  29. /*
  30.  * Harvest C
  31.  * 
  32.  * Copyright 1991 Eric W. Sink   All rights reserved.
  33.  * 
  34.  * This file contains functions for various optimizations and transformations.
  35.  * 
  36.  * 
  37.  */
  38.  
  39.  
  40. #include "conditcomp.h"
  41. #include <stdio.h>
  42. #include <string.h>
  43. #include "structs.h"
  44.  
  45.  
  46. #pragma segment Peephole
  47.  
  48.  
  49. ParseTreeVia_t
  50. BuildConstantNode(FoldValue_t * val)
  51. {
  52.     ParseTreeVia_t                  result;
  53.     if (!val->isK) {
  54.     return NULL;
  55.     }
  56.     /*
  57.      * Are we going to have problems here with signed and unsigned numbers ?
  58.      */
  59.     if (val->isint) {
  60.     if (val->isunsigned) {
  61.         FreeTree(val->init);
  62.         result = BuildTreeNode(PTF_intconstant, NULL, NULL, NULL);
  63.         SetTreeTP(result, BuildTypeRecord(0, TRC_long, SGN_unsigned));
  64.         Via(result)->LValue = 0;
  65.         Via(result)->data.number = val->uintval;
  66.     } else {
  67.         FreeTree(val->init);
  68.         result = BuildTreeNode(PTF_intconstant, NULL, NULL, NULL);
  69.         SetTreeTP(result, BuildTypeRecord(0, TRC_long, SGN_signed));
  70.         Via(result)->LValue = 0;
  71.         Via(result)->data.number = val->intval;
  72.     }
  73.     } else if (val->issymb) {
  74.     result = val->init;
  75.     } else {
  76.     FloatLitVia_t                   lit;
  77.     FreeTree(val->init);
  78.     result = BuildTreeNode(PTF_floatconstant, NULL, NULL, NULL);
  79.     SetTreeTP(result, BuildTypeRecord(0, TRC_longdouble, SGN_unknown));
  80.     Via(result)->LValue = 0;
  81.     lit = AddFloatLit(val->realval);
  82.     Via(result)->data.FLit = lit;
  83.     }
  84.     return result;
  85. }
  86.  
  87. void
  88. ConstExprValue(ParseTreeVia_t root, FoldValue_t * resp)
  89. {
  90.     FoldValue_t                     result, notK;
  91.     FoldValue_t                     t1, t2;
  92.  
  93.     notK.isK = 0;
  94.     result = notK;
  95.     result.isint = 1;
  96.     result.isstring = result.issymb = result.isoffset = 0;
  97.     result.init = root;
  98.     result.isunsigned = 0;
  99.     result.intval = 0;
  100.     result.thesymbol = NULL;
  101.     result.uintval = 0;
  102.     result.realval = 0;
  103.  
  104. #define GetBoth()  \
  105.       ConstExprValue(Via(root)->a, &t1); \
  106.       ConstExprValue(Via(root)->b, &t2); \
  107.       if ((!t1.isK) || (!t2.isK)) { \
  108.     result = notK; break; \
  109.       } result.isK = 1;
  110.  
  111.  
  112.     if (root) {
  113.     switch (Via(root)->kind) {
  114.     case PTF_array_subscript:
  115.         ConstExprValue(Via(root)->a, &t1);
  116.         ConstExprValue(Via(root)->b, &t2);
  117.         if (t1.thesymbol && t2.isK) {
  118.         result.isK = 1;
  119.         result.isint = 0;
  120.         result.isoffset = 1;
  121.         result.intval = t2.intval * GetTPSize(GetTreeTP(root));
  122.         result.thesymbol = t1.thesymbol;
  123.         }
  124.         break;
  125.     case PTF_function_call:
  126.     case PTF_postincrement:
  127.     case PTF_postdecrement:
  128.     case PTF_argument_list:
  129.     case PTF_preincrement:
  130.     case PTF_predecrement:
  131.     case PTF_deref:
  132.         break;
  133.     case PTF_gen_addrof:
  134.     case PTF_address_of:
  135.         ConstExprValue(Via(root)->a, &result);
  136.         break;
  137.     case PTF_unary_plus:
  138.         ConstExprValue(Via(root)->a, &result);
  139.         break;
  140.     case PTF_unary_minus:
  141.         ConstExprValue(Via(root)->a, &t1);
  142.         if (!t1.isK) {
  143.         result = notK;
  144.         break;
  145.         }
  146.         result.isK = 1;
  147.         result.isunsigned = t1.isunsigned;
  148.         result.isint = t1.isint;
  149.         if (t1.isint) {
  150.         if (t1.isunsigned) {
  151.             result.uintval = -t1.uintval;
  152.         } else {
  153.             result.intval = -t1.intval;
  154.         }
  155.         } else {
  156.         result.realval = -t1.realval;
  157.         }
  158.         break;
  159.     case PTF_bitwise_neg:
  160.         ConstExprValue(Via(root)->a, &t1);
  161.         if (!t1.isK) {
  162.         result = notK;
  163.         break;
  164.         }
  165.         result.isK = 1;
  166.         result.isint = 1;
  167.         result.isunsigned = t1.isunsigned;
  168.         result.intval = ~t1.intval;
  169.         result.uintval = ~t1.uintval;
  170.         result.realval = t1.intval;
  171.         break;
  172.     case PTF_logical_neg:
  173.         ConstExprValue(Via(root)->a, &t1);
  174.         if (!t1.isK) {
  175.         result = notK;
  176.         break;
  177.         }
  178.         result.isK = 1;
  179.         result.isint = 1;
  180.         result.isunsigned = 0;
  181.         if (t1.isint) {
  182.         if (t1.isunsigned) {
  183.             result.intval = !t1.uintval;
  184.         } else {
  185.             result.intval = !t1.intval;
  186.         }
  187.         } else {
  188.         result.intval = !t1.realval;
  189.         }
  190.         break;
  191.     case PTF_multiply:
  192.         GetBoth();
  193.         if (t1.isint) {
  194.         if (t2.isint) {
  195.             result.isint = 1;
  196.             if (t1.isunsigned) {
  197.             if (t2.isunsigned) {
  198.                 result.isunsigned = 1;
  199.                 result.uintval = t1.uintval * t2.uintval;
  200.             } else {
  201.                 result.isunsigned = 1;
  202.                 result.uintval = t1.uintval * t2.intval;
  203.             }
  204.             } else {
  205.             if (t2.isunsigned) {
  206.                 result.isunsigned = 1;
  207.                 result.uintval = t1.intval * t2.uintval;
  208.             } else {
  209.                 result.isunsigned = 0;
  210.                 result.intval = t1.intval * t2.intval;
  211.             }
  212.             }
  213.         } else {
  214.             result.isint = 0;
  215.             result.isunsigned = 0;
  216.             if (t1.isunsigned) {
  217.             result.realval = t1.uintval * t2.realval;
  218.             } else {
  219.             result.realval = t1.intval * t2.realval;
  220.             }
  221.         }
  222.         } else {
  223.         result.isint = 0;
  224.         result.isunsigned = 0;
  225.         if (t2.isint) {
  226.             if (t2.isunsigned) {
  227.             result.realval = t1.realval * t2.uintval;
  228.             } else {
  229.             result.realval = t1.realval * t2.intval;
  230.             }
  231.         } else {
  232.             result.realval = t1.realval * t2.realval;
  233.         }
  234.         }
  235.         break;
  236.     case PTF_divide:
  237.         GetBoth();
  238.         if (t1.isint) {
  239.         if (t2.isint) {
  240.             result.isint = 1;
  241.             if (t1.isunsigned) {
  242.             if (t2.isunsigned) {
  243.                 result.isunsigned = 1;
  244.                 result.uintval = t1.uintval / t2.uintval;
  245.             } else {
  246.                 result.isunsigned = 1;
  247.                 result.uintval = t1.uintval / t2.intval;
  248.             }
  249.             } else {
  250.             if (t2.isunsigned) {
  251.                 result.isunsigned = 1;
  252.                 result.uintval = t1.intval / t2.uintval;
  253.             } else {
  254.                 result.isunsigned = 0;
  255.                 result.intval = t1.intval / t2.intval;
  256.             }
  257.             }
  258.         } else {
  259.             result.isint = 0;
  260.             result.isunsigned = 0;
  261.             if (t1.isunsigned) {
  262.             result.realval = t1.uintval / t2.realval;
  263.             } else {
  264.             result.realval = t1.intval / t2.realval;
  265.             }
  266.         }
  267.         } else {
  268.         result.isint = 0;
  269.         result.isunsigned = 0;
  270.         if (t2.isint) {
  271.             if (t2.isunsigned) {
  272.             result.realval = t1.realval / t2.uintval;
  273.             } else {
  274.             result.realval = t1.realval / t2.intval;
  275.             }
  276.         } else {
  277.             result.realval = t1.realval / t2.realval;
  278.         }
  279.         }
  280.         break;
  281.     case PTF_modulo:
  282.         GetBoth();
  283.         result.intval = t1.intval % t2.intval;
  284.         result.realval = result.intval;
  285.         if (t1.isint && t2.isint) {
  286.         result.isint = 1;
  287.         } else {
  288.         result.isint = 0;
  289.         }
  290.         break;
  291.     case PTF_typechange:
  292.         /*
  293.          * Quite possibly something should be done here.  Many
  294.          * typechanges are actually constants.
  295.          */
  296.         break;
  297.     case PTF_add:
  298.         GetBoth();
  299.         result.intval = t1.intval + t2.intval;
  300.         result.realval = t1.realval + t2.realval;
  301.         if (t1.isint && t2.isint) {
  302.         result.isint = 1;
  303.         } else {
  304.         result.isint = 0;
  305.         }
  306.         break;
  307.     case PTF_subtract:
  308.         GetBoth();
  309.         result.intval = t1.intval - t2.intval;
  310.         result.realval = t1.realval - t2.realval;
  311.         if (t1.isint && t2.isint) {
  312.         result.isint = 1;
  313.         } else {
  314.         result.isint = 0;
  315.         }
  316.         break;
  317.     case PTF_shift_left:
  318.         GetBoth();
  319.         result.intval = t1.intval << t2.intval;
  320.         result.realval = result.intval;
  321.         if (t1.isint && t2.isint) {
  322.         result.isint = 1;
  323.         } else {
  324.         result.isint = 0;
  325.         }
  326.         break;
  327.     case PTF_shift_right:
  328.         GetBoth();
  329.         result.intval = t1.intval >> t2.intval;
  330.         result.realval = result.intval;
  331.         if (t1.isint && t2.isint) {
  332.         result.isint = 1;
  333.         } else {
  334.         result.isint = 0;
  335.         }
  336.         break;
  337.     case PTF_lessthan:
  338.         /* All these relationals should probably be handled too. */
  339.         break;
  340.     case PTF_greaterthan:
  341.         break;
  342.     case PTF_lessthaneq:
  343.         break;
  344.     case PTF_greaterthaneq:
  345.         break;
  346.     case PTF_equal:
  347.         break;
  348.     case PTF_notequal:
  349.         break;
  350.     case PTF_bitwise_and:
  351.         GetBoth();
  352.         result.intval = t1.intval & t2.intval;
  353.         result.realval = result.intval;
  354.         if (t1.isint && t2.isint) {
  355.         result.isint = 1;
  356.         } else {
  357.         result.isint = 0;
  358.         }
  359.         break;
  360.     case PTF_bitwise_xor:
  361.         GetBoth();
  362.         result.intval = t1.intval ^ t2.intval;
  363.         result.realval = result.intval;
  364.         if (t1.isint && t2.isint) {
  365.         result.isint = 1;
  366.         } else {
  367.         result.isint = 0;
  368.         }
  369.         break;
  370.     case PTF_bitwise_or:
  371.         GetBoth();
  372.         result.intval = t1.intval | t2.intval;
  373.         result.realval = result.intval;
  374.         if (t1.isint && t2.isint) {
  375.         result.isint = 1;
  376.         } else {
  377.         result.isint = 0;
  378.         }
  379.         break;
  380.     case PTF_logical_and:
  381.         GetBoth();
  382.         result.intval = t1.intval && t2.intval;
  383.         result.isint = 1;
  384.         break;
  385.     case PTF_logical_or:
  386.         GetBoth();
  387.         result.intval = t1.intval || t2.intval;
  388.         result.isint = 1;
  389.         break;
  390.     case PTF_initializer_list:
  391.         /*
  392.          * With an initializer list, we return the const value of the
  393.          * first item in the list.  The list is stored a=head, b=tail.
  394.          */
  395.         ConstExprValue(Via(root)->a, &result);
  396.         break;
  397.     case PTF_ternary:
  398.     case PTF_assign:
  399.     case PTF_mulassign:
  400.     case PTF_divassign:
  401.     case PTF_modassign:
  402.     case PTF_addassign:
  403.     case PTF_subassign:
  404.     case PTF_leftassign:
  405.     case PTF_rightassign:
  406.     case PTF_andassign:
  407.     case PTF_xorassign:
  408.     case PTF_orassign:
  409.     case PTF_commas:
  410.     case PTF_multi_initializer:
  411.     case PTF_exprstmt:
  412.     case PTF_emptystmt:
  413.     case PTF_switchcase_stmt:
  414.     case PTF_switchdefault_stmt:
  415.     case PTF_compound_stmt:
  416.     case PTF_stmt_list:
  417.     case PTF_ifthenelse_stmt:
  418.     case PTF_switch_stmt:
  419.     case PTF_while_stmt:
  420.     case PTF_dowhile_stmt:
  421.     case PTF_for_stmt:
  422.     case PTF_continue_stmt:
  423.     case PTF_break_stmt:
  424.     case PTF_return_stmt:
  425.         break;
  426.     case PTF_identifier:
  427.         result.issymb = 1;
  428.         result.thesymbol = Via(root)->data.thesymbol;
  429.         result.isint = 0;
  430.         result.isK = 0;
  431.         break;
  432.     case PTF_enumconstant:
  433.         result.isK = 1;
  434.         result.isint = 1;
  435.         result.intval = Via(Via(root)->data.thesymbol)->numbers.EnumVal;
  436.         break;
  437.     case PTF_sizeof:
  438.         result.isK = 1;
  439.         result.isint = 1;
  440.         result.intval = GetTPSize(Via(root)->data.TP);
  441.         break;
  442.     case PTF_intconstant:
  443.         result.isK = 1;
  444.         result.isint = 1;
  445.         if (isUnsignedType(GetTreeTP(root))) {
  446.         result.isunsigned = 0;
  447.         result.uintval = Via(root)->data.number;
  448.         } else {
  449.         result.intval = Via(root)->data.number;
  450.         }
  451.         break;
  452.     case PTF_floatconstant:
  453.         result.isK = 1;
  454.         result.isint = 0;
  455.         result.realval = Via(Via(root)->data.FLit)->val.num;
  456.         result.intval = result.realval;
  457.         break;
  458.     case PTF_string_literal:
  459.         result.isK = 1;
  460.         result.isint = 0;
  461.         result.isstring = 1;
  462.         break;
  463.     case PTF_struct_member:
  464.     case PTF_struct_indirect_member:
  465.     case PTF_labelled_stmt:
  466.     case PTF_goto_stmt:
  467.     default:
  468.         break;
  469.     }
  470.     }
  471.     *resp = result;
  472. }
  473.  
  474. /*
  475.  * The real problems with a constant folding routines are in getting the
  476.  * various types to fold together correctly.  Currently, I don't even think
  477.  * ecc handles unsigned constants correctly.
  478.  */
  479.  
  480. ParseTreeVia_t
  481. Constify(ParseTreeVia_t tree)
  482. {
  483.     FoldValue_t                     res;
  484.     FoldValue_t                     tK1;
  485.     ParseTreeVia_t                  newK;
  486.     if (tree) {
  487.     switch (Via(tree)->kind) {
  488.     case PTF_intconstant:
  489.     case PTF_floatconstant:
  490.     case PTF_enumconstant:
  491.     case PTF_string_literal:
  492.         return tree;
  493.         break;
  494.     default:
  495.         ConstExprValue(tree, &res);
  496.         if (res.isK && !res.issymb) {
  497.         newK = BuildConstantNode(&res);
  498.         return newK;
  499.         }
  500.         break;
  501.     }
  502.     switch (Via(tree)->kind) {
  503.     case PTF_multiply:
  504.         Via(tree)->a = Constify(Via(tree)->a);
  505.         Via(tree)->b = Constify(Via(tree)->b);
  506.         return tree;
  507.         break;
  508.     case PTF_divide:
  509.         Via(tree)->a = Constify(Via(tree)->a);
  510.         Via(tree)->b = Constify(Via(tree)->b);
  511.         return tree;
  512.         break;
  513.     case PTF_modulo:
  514.         Via(tree)->a = Constify(Via(tree)->a);
  515.         Via(tree)->b = Constify(Via(tree)->b);
  516.         return tree;
  517.         break;
  518.     case PTF_add:
  519.         Via(tree)->a = Constify(Via(tree)->a);
  520.         Via(tree)->b = Constify(Via(tree)->b);
  521.         return tree;
  522.         break;
  523.     case PTF_subtract:
  524.         Via(tree)->a = Constify(Via(tree)->a);
  525.         Via(tree)->b = Constify(Via(tree)->b);
  526.         return tree;
  527.         break;
  528.     case PTF_shift_left:
  529.         Via(tree)->a = Constify(Via(tree)->a);
  530.         Via(tree)->b = Constify(Via(tree)->b);
  531.         return tree;
  532.         break;
  533.     case PTF_shift_right:
  534.         Via(tree)->a = Constify(Via(tree)->a);
  535.         Via(tree)->b = Constify(Via(tree)->b);
  536.         return tree;
  537.         break;
  538.     case PTF_lessthan:
  539.         Via(tree)->a = Constify(Via(tree)->a);
  540.         Via(tree)->b = Constify(Via(tree)->b);
  541.         return tree;
  542.         break;
  543.     case PTF_greaterthan:
  544.         Via(tree)->a = Constify(Via(tree)->a);
  545.         Via(tree)->b = Constify(Via(tree)->b);
  546.         return tree;
  547.         break;
  548.     case PTF_lessthaneq:
  549.         Via(tree)->a = Constify(Via(tree)->a);
  550.         Via(tree)->b = Constify(Via(tree)->b);
  551.         return tree;
  552.         break;
  553.     case PTF_greaterthaneq:
  554.         Via(tree)->a = Constify(Via(tree)->a);
  555.         Via(tree)->b = Constify(Via(tree)->b);
  556.         return tree;
  557.         break;
  558.     case PTF_equal:
  559.         Via(tree)->a = Constify(Via(tree)->a);
  560.         Via(tree)->b = Constify(Via(tree)->b);
  561.         return tree;
  562.         break;
  563.     case PTF_notequal:
  564.         Via(tree)->a = Constify(Via(tree)->a);
  565.         Via(tree)->b = Constify(Via(tree)->b);
  566.         return tree;
  567.         break;
  568.     case PTF_bitwise_and:
  569.         Via(tree)->a = Constify(Via(tree)->a);
  570.         Via(tree)->b = Constify(Via(tree)->b);
  571.         return tree;
  572.         break;
  573.     case PTF_bitwise_xor:
  574.         Via(tree)->a = Constify(Via(tree)->a);
  575.         Via(tree)->b = Constify(Via(tree)->b);
  576.         return tree;
  577.         break;
  578.     case PTF_bitwise_or:
  579.         Via(tree)->a = Constify(Via(tree)->a);
  580.         Via(tree)->b = Constify(Via(tree)->b);
  581.         return tree;
  582.         break;
  583.     case PTF_logical_and:
  584.         Via(tree)->a = Constify(Via(tree)->a);
  585.         Via(tree)->b = Constify(Via(tree)->b);
  586.         return tree;
  587.         break;
  588.     case PTF_logical_or:
  589.         Via(tree)->a = Constify(Via(tree)->a);
  590.         Via(tree)->b = Constify(Via(tree)->b);
  591.         return tree;
  592.         break;
  593.     case PTF_ternary:
  594.         Via(tree)->a = Constify(Via(tree)->a);
  595.         Via(tree)->b = Constify(Via(tree)->b);
  596.         Via(tree)->c = Constify(Via(tree)->c);
  597.         return tree;
  598.         break;
  599.     case PTF_assign:
  600.     case PTF_mulassign:
  601.     case PTF_divassign:
  602.     case PTF_modassign:
  603.     case PTF_addassign:
  604.     case PTF_subassign:
  605.     case PTF_leftassign:
  606.     case PTF_rightassign:
  607.     case PTF_andassign:
  608.     case PTF_xorassign:
  609.     case PTF_orassign:
  610.         Via(tree)->b = Constify(Via(tree)->b);
  611.         return tree;
  612.         break;
  613.     case PTF_stmt_list:
  614.         Via(tree)->a = Constify(Via(tree)->a);
  615.         Via(tree)->b = Constify(Via(tree)->b);
  616.         return tree;
  617.         break;
  618.     case PTF_ifthenelse_stmt:
  619.         Via(tree)->a = Constify(Via(tree)->a);
  620.         Via(tree)->b = Constify(Via(tree)->b);
  621.         Via(tree)->c = Constify(Via(tree)->c);
  622.         ConstExprValue(Via(tree)->a, &tK1);
  623.         if (tK1.isK) {
  624.         if (tK1.isint) {
  625.             if (tK1.intval) {
  626.             return Via(tree)->b;
  627.             } else {
  628.             if (Via(tree)->c) {
  629.                 return Via(tree)->c;
  630.             } else {
  631.                 FreeTree(tree);
  632.                 return BuildTreeNode(PTF_NOP, NULL, NULL, NULL);
  633.             }
  634.             }
  635.         }
  636.         }
  637.         return tree;
  638.         break;
  639.     case PTF_exprstmt:
  640.     case PTF_compound_stmt:
  641.         Via(tree)->a = Constify(Via(tree)->a);
  642.         return tree;
  643.         break;
  644.     case PTF_while_stmt:
  645.         Via(tree)->a = Constify(Via(tree)->a);
  646.         Via(tree)->b = Constify(Via(tree)->b);
  647.         ConstExprValue(Via(tree)->a, &tK1);
  648.         if (tK1.isK) {
  649.         if (tK1.isint) {
  650.             if (!tK1.intval) {
  651.             return BuildTreeNode(PTF_NOP, NULL, NULL, NULL);
  652.             }
  653.         }
  654.         }
  655.         return tree;
  656.         break;
  657.     case PTF_dowhile_stmt:
  658.         Via(tree)->a = Constify(Via(tree)->a);
  659.         Via(tree)->b = Constify(Via(tree)->b);
  660.         return tree;
  661.         break;
  662.     case PTF_for_stmt:
  663.         Via(tree)->a = Constify(Via(tree)->a);
  664.         Via(tree)->b = Constify(Via(tree)->b);
  665.         Via(tree)->c = Constify(Via(tree)->c);
  666.         SetTreeFour(tree, Constify(GetTreeFour(tree)));
  667.         return tree;
  668.         break;
  669.     case PTF_return_stmt:
  670.         Via(tree)->a = Constify(Via(tree)->a);
  671.         return tree;
  672.         break;
  673.     default:
  674.         break;
  675.     }
  676.     }
  677.     return tree;
  678. }
  679.  
  680. /* Optimizations... */
  681.  
  682. int
  683. isRegDirect(LocAMVia_t loc)
  684. {
  685.     if (!loc)
  686.     return 0;
  687.     if (GetLocAM(loc) == M68am_DReg) {
  688.     return 1;
  689.     } else if (GetLocAM(loc) == M68am_ARegDirect) {
  690.     return 1;
  691.     } else {
  692.     return 0;
  693.     }
  694. }
  695.  
  696. InstVia_t
  697. DeleteInst(InstVia_t inst)
  698. /*
  699.  * Removes an instruction from the list, and returns the instruction just
  700.  * before it.
  701.  */
  702. {
  703. #ifdef DoDelete
  704.     InstVia_t                       result;
  705.     if (Via(inst)->prev) {
  706.     Via(Via(inst)->prev)->next = Via(inst)->next;
  707.     }
  708.     if (Via(inst)->next) {
  709.     Via(Via(inst)->next)->prev = Via(inst)->prev;
  710.     }
  711.     result = Via(inst)->prev;
  712.     Efree(inst);
  713.     return result;
  714. #else
  715.     Via(inst)->OP = M68op_DELETED;
  716.     return inst;
  717. #endif
  718. }
  719.  
  720. int
  721. isLABEL(InstVia_t a)
  722. {
  723.     if (!a)
  724.     return 0;
  725.     switch (Via(a)->OP) {
  726.     case M68op_DATALABEL:
  727.     case M68op_CODELABEL:
  728.     case M68op_STRINGLABEL:
  729.     case M68op_LCOMM:
  730.     case M68op_COMM:
  731.     case M68op_LABEL:
  732.     return 1;
  733.     default:
  734.     return 0;
  735.     }
  736. }
  737.  
  738. int
  739. isBRANCH(InstVia_t a)
  740. {
  741.     if (!a)
  742.     return 0;
  743.     switch (Via(a)->OP) {
  744.     case M68op_BRA:
  745.     case M68op_BCC:
  746.     case M68op_BCS:
  747.     case M68op_BEQ:
  748.     case M68op_BGE:
  749.     case M68op_BGT:
  750.     case M68op_BHI:
  751.     case M68op_BLE:
  752.     case M68op_BLS:
  753.     case M68op_BLT:
  754.     case M68op_BMI:
  755.     case M68op_BNE:
  756.     case M68op_BPL:
  757.     case M68op_BVC:
  758.     case M68op_BVS:
  759.     return 1;
  760.     default:
  761.     return 0;
  762.     }
  763. }
  764.  
  765. int
  766. EquivAddress(InstVia_t a, InstVia_t b)
  767. {
  768.     InstVia_t                       c;
  769.     /* Return true if the two instructions are the same address */
  770.     if (a == b)
  771.     return 1;
  772.     /* check forward from a */
  773.     if (isLABEL(a)) {
  774.     c = Via(a)->next;
  775.     while (c) {
  776.         if (c == b)
  777.         return 1;
  778.         if (isLABEL(c)) {
  779.         c = Via(c)->next;
  780.         } else {
  781.         c = NULL;
  782.         }
  783.     }
  784.     c = Via(a)->prev;
  785.     while (c) {
  786.         if (c == b)
  787.         return 1;
  788.         if (isLABEL(c)) {
  789.         c = Via(c)->prev;
  790.         } else {
  791.         c = NULL;
  792.         }
  793.     }
  794.     } else if (Via(b)->OP == M68op_LABEL) {
  795.     c = Via(b)->next;
  796.     while (c) {
  797.         if (c == a)
  798.         return 1;
  799.         if (isLABEL(c)) {
  800.         c = Via(c)->next;
  801.         } else {
  802.         c = NULL;
  803.         }
  804.     }
  805.     c = Via(b)->prev;
  806.     while (c) {
  807.         if (c == a)
  808.         return 1;
  809.         if (isLABEL(c)) {
  810.         c = Via(c)->prev;
  811.         } else {
  812.         c = NULL;
  813.         }
  814.     }
  815.     } else
  816.     return 0;
  817. }
  818.  
  819. void
  820. Optimize68(InstListVia_t Codes)
  821. {
  822.     InstVia_t                       curinst;
  823.     curinst = Via(Codes)->head;
  824.     while (curinst) {
  825.     int                             deleted;
  826.     deleted = 0;
  827.     if (isBRANCH(curinst)) {
  828.         /*
  829.          * We SHOULD check for ANY branch here, and insert a nop or
  830.          * something.
  831.          */
  832.         if (Via(curinst)->next) {
  833.         if (Via(Via(curinst)->next)->OP == M68op_LABEL) {
  834.             if (EquivAddress(Via(curinst)->next, Via(GetLocLabel(Via(curinst)->left))->M68kDef.where)) {
  835.             curinst = DeleteInst(curinst);
  836.             curinst = Via(curinst)->prev;
  837.             deleted = 1;
  838.             }
  839.         }
  840.         /*
  841.          * The inst after the branch should probably be deleted. It
  842.          * is dead code.
  843.          */
  844.         }
  845.     } else if (Via(curinst)->OP == M68op_MOVE) {
  846.         /*
  847.          * There are many other optimizations which can be done on move
  848.          * instructions.
  849.          */
  850.         if (GetLocAM(Via(curinst)->left) == M68am_Immediate) {
  851.         if (GetLocAM(Via(curinst)->right) == M68am_DReg) {
  852.             if ((GetLocConstant(Via(curinst)->left) <= 127) && (GetLocConstant(Via(curinst)->left)
  853.                                  >= -128)) {
  854.             Via(curinst)->OP = M68op_MOVEQ;
  855.             Via(curinst)->SZ = M68sz_none;
  856.             }
  857.         }
  858.         } else if (SameLocation(Via(curinst)->left, Via(curinst)->right)) {
  859.         curinst = DeleteInst(curinst);
  860.         deleted = 1;
  861.         } else if (Via(curinst)->prev) {
  862.         if (Via(Via(curinst)->prev)->OP == M68op_MOVE) {
  863.             if (Via(Via(curinst)->prev)->SZ == Via(curinst)->SZ)
  864.             if (SameLocation(Via(Via(curinst)->prev)->right, Via(curinst)->left) &&
  865.                 SameLocation(Via(Via(curinst)->prev)->left, Via(curinst)->right)) {
  866.                 curinst = DeleteInst(curinst);
  867.                 deleted = 1;
  868.             }
  869.         }
  870.         }
  871.     } else if (Via(curinst)->OP == M68op_ADD) {
  872.         if (GetLocAM(Via(curinst)->left) == M68am_Immediate) {
  873.         if ((GetLocConstant(Via(curinst)->left) <= 8) && (GetLocConstant(Via(curinst)->left)
  874.                                   >= 1)) {
  875.             Via(curinst)->OP = M68op_ADDQ;
  876.         }
  877.         }
  878.     } else if (Via(curinst)->OP == M68op_SUB) {
  879.         if (GetLocAM(Via(curinst)->left) == M68am_Immediate) {
  880.         if ((GetLocConstant(Via(curinst)->left) <= 8) && (GetLocConstant(Via(curinst)->left)
  881.                                   >= 1)) {
  882.             Via(curinst)->OP = M68op_SUBQ;
  883.         }
  884.         }
  885.     }
  886.     if (!deleted) {
  887.         curinst = Via(curinst)->next;
  888.     }
  889.     }
  890. }
  891.